'''
FilePath: \src\data\get_infomation.py
Description: 将读取的信息转化为算法所需要的信息

Author: xy
Date: 2025-06-11 15:39:20
Version: 
'''

# 标准库
import copy

# 第三方库

# 自定义库
from data.date_loader import Data

class Info:
    def __init__(self,path):
        self.data=Data(path)
        self.data.run()
        self.start_index=[]
        self.list_stage=self.get_S(self.data)# 浇次 b 的生产阶段集合
        self.M_bs=self.get_M_bs(self.data)# 浇次b在阶段s可选机器集合

        self.list_stage_withnull=copy.deepcopy(self.list_stage)#将跳过的阶段变[-1] [0,1,3]->[0,1,-1,3]
        for i in self.list_stage_withnull:
            missing_numbers = [j for j in range(self.data.num_stage) if j not in i]
            for j in missing_numbers:
                i.insert(j,-1)
            



    def get_info_ga(self):
        '''
        description: 为遗传算法准备信息
        param {*} 文件路径
        return {*}
        '''
        data=self.data
        list_cast_info=[]
        num_stage=data.num_stage# 阶段数量
        M_bs=self.get_M_bs(data)# 浇次b在阶段s可选机器集合
        index=0
        fur=[]
        for i in range(len(data.I)):
            fur.append([index,index+data.I[i].num_Fur])
            I_data=[]# 浇次信息
            I_data.append(data.I[i].num_Fur)
            I_data.append(self.list_stage[i])
            I_data.append(M_bs[i])
            list_cast_info.append(I_data)
            index+=data.I[i].num_Fur

        return num_stage,list_cast_info,self.start_index,self.list_stage,self.M_bs

    def get_S(self,data):
        S = [[] for i in range(len(data.I))]
        index=0
        for i in range(len(data.I)):
            self.start_index.append(index)
            for j in data.I[i].route:
                name=j
                if type(j) != str:
                    name=j[0]
                for k in data.device:
                    if k.name == name:
                        S[i].append(k.type_id)
            index+=data.I[i].num_Fur
            if i==len(self.data.I)-1:
                self.start_index.append(index)
        return S

    def get_M_bs(self,data):
        M_bs = [[[] for j in range(data.num_stage)] for i in range(len(data.I))]
        for i in range(len(data.I)):
            for j in data.I[i].route:
                name=[]
                if type(j) != str:
                    for l in j:
                        name.append(l)
                else:
                    name.append(j)
                for z in name:
                    for k in data.device:
                        if k.name == z:
                            M_bs[i][k.type_id].append(k.id)


        return M_bs
        

    def get_processtime(self,population):
        '''
        description: 根据染色体获取加工时间表
        '''
        time_table=[[0 for i in range(self.data.num_stage) ]for j in range(self.data.total_Fur)]
        o=0
        num_fur=self.data.I[0].num_Fur
        for i in range(len(population)):
            if i>=num_fur:
                o+=1
                num_fur+=self.data.I[o].num_Fur
            for j in range(len(population[i])):
                if population[i][j]!=0:
                    machine_id=self.data.stage_device[j][population[i][j]-1]
                    time_table[i][j]=self.data.device[machine_id].process_speed[self.data.I[o].name]
        return time_table

    def get_transfertime(self,population):
        '''
        description: 根据染色体获取移动时间表
        '''
        start_index=self.start_index
        list_stage=self.list_stage
        trans_time=[[0 for i in range(self.data.num_stage) ]for j in range(self.data.total_Fur)]
        for i in range(len(start_index)-1):  # 浇次
            stage=list_stage[i]# 阶段
            if i<len(start_index)-1:
                for j in range(start_index[i],start_index[i+1]):
                    for s in range(len(stage)-1,0,-1):
                        machine_id_start=self.data.stage_device[stage[s-1]][population[j][stage[s-1]]-1]
                        machine_id_end=self.data.stage_device[stage[s]][population[j][stage[s]]-1]
                        if machine_id_end in self.data.device[machine_id_start].transfertime:
                            trans_time[j][stage[s]]=self.data.device[machine_id_start].transfertime[machine_id_end]
                        else:
                             trans_time[j][stage[s]]=10
            else:
                for j in range(start_index[i],len(chromosome)):
                    for s in range(len(stage)-1,0,-1):
                        machine_id_start=self.data.stage_device[j][population[j][stage[s-1]]-1]
                        machine_id_end=self.data.stage_device[j][population[j][stage[s]]-1]
                        if machine_id_end in self.data.device[machine_id_start].transfertime:
                            trans_time[j][stage[s]]=self.data.device[machine_id_start].transfertime[machine_id_end]
                        else:
                             trans_time[j][stage[s]]=10

        return trans_time

    def get_starttime(self,population,pro_timetable,trans_timetable):
        '''
        description: 
        param {*} self
        param {*} population
        param {*} pro_timetable
        param {*} trans_timetable
        return {*}
        '''
        
        start_timetable=[0 for i in range(self.data.total_Fur)]
        index=0
        c={}
        for i in range(len(self.data.I)):
            machine=population[index][-1]
            if machine not in c:
                start_timetable[index]=sum(pro_timetable[index][:-1])+sum(trans_timetable[index])
                c[machine]=sum(pro_timetable[index])+sum(trans_timetable[index])
            else:
                c[machine]+=self.data.I[i].change_time
                start_timetable[index]=c[machine]
                c[machine]+=pro_timetable[index][-1]
            
            for j in range(1,self.data.I[i].num_Fur):
                start_timetable[index+j]=start_timetable[index+j-1]+pro_timetable[index+j-1][-1]
                c[machine]+=pro_timetable[index+j][-1]
            index+=self.data.I[i].num_Fur

        return start_timetable

    def get_info(self,population):
        pro_timetable=self.get_processtime(population)
        trans_timetable=self.get_transfertime(population)
        start_time=self.get_starttime(population,pro_timetable,trans_timetable)
        return pro_timetable,trans_timetable,start_time
